package com.bytz.modules.hikvision.service.impl;

import com.bytz.modules.hikvision.HCNetSDK;
import com.bytz.modules.hikvision.service.IHikvisionService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@AllArgsConstructor
public class HikvisionServiceImpl implements IHikvisionService {
    private final HCNetSDK hCNetSDK;
    private static final Map<String, Integer> lUserIdMap = new HashMap<>();
    private static final Map<Integer, Integer> lHandleMap = new HashMap<>();

    /**
     * 设备登录
     * @param ipadress IP地址
     * @param user  用户名
     * @param psw  密码
     * @param port 端口，默认8000
     */
    @Override
    public int login_V40(String ipadress, String user, String psw, short port) {
        //注册
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(ipadress.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, ipadress.length());
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(user.getBytes(), 0, m_strLoginInfo.sUserName, 0, user.length());
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(psw.getBytes(), 0, m_strLoginInfo.sPassword, 0, psw.length());
        m_strLoginInfo.wPort = port;
        m_strLoginInfo.bUseAsynLogin = false;
        m_strLoginInfo.write();
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
        int lUserID = -1;
        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID == -1) {
            throw new RuntimeException("登录失败，错误码为" + hCNetSDK.NET_DVR_GetLastError());
        } else {
            lUserIdMap.put(ipadress, lUserID);
            // TODO 将lUserID存入数据库
            System.out.println("登录成功！");
            m_strDeviceInfo.read();
//            iCharEncodeType = m_strDeviceInfo.byCharEncodeType;
            return lUserID;
        }
    }

    /**
     * 布防
     * @param lUserID 登录后返回的id
     * @return 布防结果
     */
    @Override
    public int setupAlarmChan_V41(int lUserID) {
        // 这里需要对设备进行相应的参数设置，不设置或设置错误都会导致设备注册失败
        HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
        m_strAlarmInfo.dwSize = m_strAlarmInfo.size();
        // 智能交通布防优先级：0 - 一等级（高），1 - 二等级（中），2 - 三等级（低）
        m_strAlarmInfo.byLevel = 1;
        // 智能交通报警信息上传类型：0 - 老报警信息（NET_DVR_PLATE_RESULT）, 1 - 新报警信息(NET_ITS_PLATE_RESULT)
        m_strAlarmInfo.byAlarmInfoType = 1;
        // 布防类型(仅针对门禁主机、人证设备)：0 - 客户端布防(会断网续传)，1 - 实时布防(只上传实时数据)
        m_strAlarmInfo.byDeployType = 1;
        // 抓拍，这个类型要设置为 0 ，最重要的一点设置
        m_strAlarmInfo.byFaceAlarmDetection = 0;
        m_strAlarmInfo.write();
        // 布防成功，返回布防成功的数据传输通道号
        int lHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
        if (lHandle == -1){
            throw new RuntimeException("设置报警通道失败，错误码为" + hCNetSDK.NET_DVR_GetLastError());
        }
        lHandleMap.put(lUserID, lHandle);
        // TODO 将lHandle存入数据库
        return lHandle;
    }

    /**
     * 撤防
     * @param lUserID 登录后返回的id
     */
    @Override
    public void closeAlarmChan_V30(int lUserID) {
        if (hCNetSDK.NET_DVR_CloseAlarmChan_V30(lHandleMap.get(lUserID))) {
            // TODO 删除数据库中的lHandle
            lHandleMap.remove(lUserID);
        }else {
            throw new RuntimeException("撤防失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
        }

    }

    @Override
    public void logout(String ipadress) {
        // TODO 释放相关资源（如撤防）

        if (hCNetSDK.NET_DVR_Logout(lUserIdMap.get(ipadress))) {
            // TODO 删除数据库中的lUserID
            lUserIdMap.remove(ipadress);
        }else {
            throw new RuntimeException("退出登录失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
        }
    }

}
